////////////////////////////////////////////////////////////////////////////////// 	 
//如果需要使用OS,则包括下面的头文件即可.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <math.h>
#include <stdint.h>
#include <rtthread.h>
#include "sys.h"

#define SYMBOL_GLOBALS
#include "sys_timer.h"
#undef SYMBOL_GLOBALS

static volatile uint32_t lo_unElapsedSecs, lo_unElapsedMSecs, lo_unCurSysticks;

static uint8_t lo_ubSysticksOfOneUS = 0;						//* 1微秒多少个时钟节拍
static uint8_t lo_ubMillisecondsOfOneSystick = 0;	//* 一个时钟节拍多少毫秒
 
extern void rt_interrupt_enter(void); 
extern void rt_interrupt_leave(void); 
extern void rt_tick_increase(void); 

//* systick中断服务函数,使用ucos时用到
void SysTick_Handler(void)
{	
  rt_interrupt_enter(); 
  {
    rt_tick_increase(); 
  
    lo_unCurSysticks++;
    lo_unElapsedMSecs += lo_ubMillisecondsOfOneSystick;
    
    if(!(lo_unCurSysticks % RT_TICK_PER_SECOND))
      lo_unElapsedSecs++; 
  }  
	rt_interrupt_leave(); 
}
			   
void OSSystimerInit(void)
{
	uint32_t unReload;
	
	SysTick_Config(500);
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//* 选择外部时钟：HCLK/8
	lo_ubSysticksOfOneUS = (SystemCoreClock / 8) / 1000000;	
	unReload = SystemCoreClock / 8;												//* 每秒钟的计数次数，系统时钟8分频，所以这里除以8
	unReload = unReload / RT_TICK_PER_SECOND;							//* 根据OS的系统时钟节拍数来确定定时器计数值，1 / OS_TICKS_PER_SEC计算一个节拍需要多少秒，与unReload相乘后就是一个定时器滴答多少次正好是一个时钟节拍
																												//* SysTick->LOAD为24位寄存器,最大值:16777216,在72M下,约合1.86s左右	
	
	lo_ubMillisecondsOfOneSystick = 1000 / RT_TICK_PER_SECOND;	//* 代表OS可以延时的最小单位	   

	SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;   					//* 使能Systick中断
	SysTick->LOAD  = unReload - 1; 												//* 每(1 / OS_TICKS_PER_SEC)秒中断一次,也就是进行一次任务调度
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;   					//* 启动Systick定时器
	lo_unElapsedSecs  = 0; 
	lo_unElapsedMSecs = 0; 
	lo_unCurSysticks  = 0;
}								    

void delay_us(uint32_t unDelayUS)
{		
	uint32_t unTicks;
	uint32_t unOldTime, unNowTime, unTimeCnt = 0;
	uint32_t unReload = SysTick->LOAD; //* 当前计数值
	
	unTicks   = unDelayUS * lo_ubSysticksOfOneUS; //* 需要的节拍数
	unTimeCnt = 0;
	rt_enter_critical();
	{
		unOldTime = SysTick->VAL; //* 此时的计数值
		while(TRUE)
		{
			unNowTime = SysTick->VAL;
			if(unNowTime != unOldTime)
			{
				if(unNowTime < unOldTime)
					unTimeCnt += unOldTime - unNowTime;
				else 
					unTimeCnt += unReload - unNowTime + unOldTime;	
				
				unOldTime = unNowTime;
				if(unTimeCnt >= unTicks)	//* 延时到达
					break;
			}
		}
	}
	rt_exit_critical();							    
}

void DelayusByCount(uint16_t usDelayUS)
{
	uint32_t	i;
	uint16_t j;
	for(j=0;j<usDelayUS;j++)
	{
		for(i=0;i<81;i++);
	}
}

uint32_t GetElapsedSecs(void)
{
	return lo_unElapsedSecs;
}

uint32_t GetElapsedMSecs(void)
{
	return lo_unElapsedMSecs;
}

uint32_t GetCurSysticks(void)
{
	return lo_unCurSysticks;
}
